package jBittorrentAPI.strategy;

import jBittorrentAPI.DownloadManager;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;

public class RarestFirstAlgoritme implements PiecePickingStrategy {
	
	public DownloadManager dm;
	
	public RarestFirstAlgoritme(DownloadManager dm){
		this.dm = dm;
	}
	@Override
	public int choosingAlgoritme(ArrayList<Integer> possible) {
		return chooseRarestFirstAlgoritme(possible);
	}
	
	@Override
	public synchronized void removeIndex(int i) {
		// do nothing
	}
	
	private synchronized int chooseRarestFirstAlgoritme(ArrayList<Integer> possible){
		synchronized (dm.getPeerAvailabilies()){
			ArrayList<Integer> pieces = new ArrayList<Integer>();

			Set<String> keyset = dm.getPeerAvailabilies().keySet();
			for (Iterator<String> i = keyset.iterator(); i.hasNext(); ) {
				String peer = (String) i.next();
				BitSet set = dm.getPeerAvailabilies().get(peer);

				if(pieces.size() == 0){
					for(int j = 0; j < possible.size(); j++){
						pieces.add(((set.get(possible.get(j)) == true) ? 1 : 0));
					}
				}else{
					for(int j = 0; j < possible.size(); j++){
						pieces.set(j, pieces.get(j)  + ((set.get(possible.get(j)) == true) ? 1 : 0));
					}
				}
			}

			ArrayList<Integer> piecesToRequest = new ArrayList<Integer>();
			int smallestValue = 10000;
			for(int i = 0; i < pieces.size(); i++){
				int pieceSize = pieces.get(i);
				if(pieceSize < smallestValue){
					smallestValue = pieceSize;
					piecesToRequest.clear();
					piecesToRequest.add(possible.get(i));
				}else if (pieceSize == smallestValue){
					piecesToRequest.add(possible.get(i));
				}
			}

			pieces = null;

			if(piecesToRequest.size() == 1){
				dm.setRequested(piecesToRequest.get(0), true);
				return piecesToRequest.get(0);
			}else if(piecesToRequest.size() > 1){
				Random r = new Random(System.currentTimeMillis());
				int index = piecesToRequest.get(r.nextInt(piecesToRequest.size()));
				dm.setRequested(index, true);
				piecesToRequest = null;
				return index;
			}else{
				return -1;
			}
		}
	}

}
